package com.ql.mangersystem.controller;

import cn.hutool.core.io.FileUtil;
import com.ql.mangersystem.common.HoneyLogs;
import com.ql.mangersystem.common.LogType;
import com.ql.mangersystem.common.Page;
import com.ql.mangersystem.common.Result;
import com.ql.mangersystem.entity.dto.FilePageDTO;
import com.ql.mangersystem.entity.dto.FileSearchDTO;
import com.ql.mangersystem.entity.dto.RenameDTO;
import com.ql.mangersystem.entity.vo.DownloadVo;
import com.ql.mangersystem.entity.vo.FileVo;
import com.ql.mangersystem.exception.ServiceException;
import com.ql.mangersystem.service.FileOperationService;
import com.ql.mangersystem.service.FileService;
import io.swagger.annotations.Api;

import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.net.URLEncoder;
import java.time.LocalDateTime;
import java.util.List;
import java.util.UUID;

@RequestMapping("/file")
@RestController
@Slf4j
@Api("文件接口")
@CrossOrigin(value = "http://localhost:5173/")
public class FileController {

    private static final String FILE_PATH = "D:\\path";
    @Value("${ip:localhost}")
    String ip;

    @Value("${server.port}")
    String port;
    @Resource
    private FileService fileService;
    @Resource
    private FileOperationService fileOperationService;

    @ApiOperation("上传文件")
    @PostMapping("/upload")
    @HoneyLogs(operation = "文件",type =LogType.ADD)
    public Result upload(@RequestParam("userId") Integer userId,@RequestParam("file") MultipartFile file){
        String originalFilename = file.getOriginalFilename();
        assert originalFilename != null;
        String suffix = originalFilename.substring(originalFilename.lastIndexOf("."));
        //使用UUID重新生成文件名，防止文件名重复造成文件覆盖
        String newName = UUID.randomUUID() + suffix;
        if (!FileUtil.exist(FILE_PATH)) {
            FileUtil.mkdir(FILE_PATH);  // 如果当前文件的父级目录不存在，就创建
        }
        String url = "http://" + ip + ":"+ port +"/api" +"/path" +"/" + newName;
        int result = fileService.insert(originalFilename,newName,url,userId);
        Integer fileId = fileService.selectByNewName(newName);
        int res = fileOperationService.uploadInsert(fileId);
        try {
            File saveFile = new File(FILE_PATH , newName);
            file.transferTo(saveFile);  // 存储文件到本地的磁盘里面
            return Result.success(url);  //返回文件的链接，这个链接就是文件的下载地址，这个下载地址就是我的后台提供出来的
        } catch (Exception e) {
//            e.printStackTrace();
        }
        if (result<=0&&res<=0){
            return Result.error("上传失败");
        }
        System.out.println("上传");
        return Result.success();
    }
    @ApiOperation("下载文件")
    @GetMapping("/download/{id}")
    public void download(@PathVariable("id") Integer id, HttpServletResponse response) throws IOException {
        DownloadVo vo = fileService.selectById(id);
        LocalDateTime now = LocalDateTime.now();
        int result = fileOperationService.insertDownload(id,now);
        if (result<=0){
            throw new ServiceException(500,"系统错误");
        }
//        System.out.println(vo);
        response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(vo.getOriginalName(), "UTF-8"));
        String fileName = FILE_PATH + File.separator + vo.getNowName();
        try {
            byte[] bytes = FileUtil.readBytes(fileName);
            ServletOutputStream outputStream = response.getOutputStream();
            outputStream.write(bytes);  // 数组是一个字节数组，也就是文件的字节流数组
            outputStream.flush();
            outputStream.close();
        }catch (Exception e){
//            e.printStackTrace();
        }
    }
    @ApiOperation("文件分页查询")
    @PostMapping("/page")
    public Result page(@RequestBody FilePageDTO filePageDTO) {
        Page<FileVo> page = fileService.selectByPage(filePageDTO);
        return Result.success(page);
    }
    //根据id输出下载地址
    @ApiOperation("根据id输出下载地址")
    @GetMapping("/backUrl")
    public Result backUrl(@RequestParam("id") Integer id) {
        String url = "http://" + ip + ":"+ port +"/api/file/download/"+id;
        return Result.success(url);
    }
    @ApiOperation("根据id逻辑删除")
    @PutMapping("/logicDelete")
    @HoneyLogs(operation = "文件",type =LogType.DELETE)
    public Result logicDelete(@RequestParam("id") Integer id) {
        int result = fileService.logicDelete(id);
        if (result<=0){
            return Result.error("删除失败");
        }
        return Result.success("删除成功");
    }
    @ApiOperation("根据id修改文件名")
    @PutMapping("/reName")
    @HoneyLogs(operation = "文件",type =LogType.UPDATE)
    public Result reName(@RequestBody RenameDTO renameDTO) {
        int result = fileService.rename(renameDTO);
        int res = fileOperationService.rename(renameDTO.getId());
        if (result<=0&&res<=0){
            return Result.error("修改失败");
        }
        return Result.success("修改成功");
    }
    @ApiOperation("根据文件名模糊查询")
    @PostMapping("/searchByName")
    public Result searchByName(@RequestBody FileSearchDTO fileSearchDTO) {
        Page<FileVo> page = fileService.selectByName(fileSearchDTO);
        return Result.success(page);
    }
    @ApiOperation("批量删除")
    @HoneyLogs(operation = "文件",type =LogType.BATCH_DELETE)
    @PutMapping("/logicDelBatch")
    public Result logicDelBatch(@RequestParam List<Integer> ids){
        int result = fileService.logicDelBatch(ids);
        int res =fileOperationService.logicDelBatch(ids);
        if (res<=0&&result<=0){
            return Result.error("删除失败");
        }
        return Result.success();
    }
}

